package com.j.lemon.learn.thread.threadPool;

import java.util.concurrent.*;

/**
 * 线程池
 * 创建方式：
 * ExecutorService executorService = new Executors.newFixedThreadPool()
 * 固定数量的线程池
 *
 * ExecutorService executorService = new Executors.newSingleThreadPool()
 * 只有一个线程的线程池
 *
 * ExecutorService executorService = new Executors.newCachedThreadPool()
 * 不固定数量的线程池
 *
 * ExecutorService executorService = new Executors.newScheduledThreadPool()
 * 每多少秒执行一次线程任务的线程池
 *
 * <p>
 * 自定义：ExecutorService executorService = new ThreadPoolExecutor(int corePoolSize,
 * int maximumPoolSize,
 * long keepAliveTime,
 * TimeUnit unit,
 * BlockingQueue<Runnable> workQueue,
 * ThreadFactory threadFactory,
 * RejectedExecutionHandler handler)
 * corePoolSize:初始化线程数量
 * <p>
 * maximumPoolSize：最大线程数量
 * <p>
 * long keepAliveTime：线程池中的线程数量大于corePoolSize时，空闲线程的多久后回收
 * <p>
 * BlockingQueue<Runnable> workQueue：任务队列类型 ↓
 * <p>
 * new SynchronousQueue<Runnable>())
 * 直接被提交的队列，里面只有一个任务，来一个执行一个，执行完了下一个才能进来别执行
 * <p>
 * new LinkedBlockingQueue<Runnable>()
 * 无界的任务队列，最大长度无限
 * <p>
 * new ArrayBlockingQueue<Runnable>()
 * 有界的任务队列
 * <p>
 * new PriorityBlockingQueue<Runnable>()
 * 有优先级的无界队列
 * <p>
 * RejectedExecutionHandler：拒绝策略，当队列满了的时候，再有任务过来，如何进行处理。↓
 * AbortPolicy:抛出异常，停止任务
 * CallerRunsPolicy:调用者运行，但是数量大时，性能急剧下降
 * DiscardPolicy:抛弃进入不到队列的任务，不做任何处理，允许丢失情况下最好的策略。
 * ThreadFactory:线程创建工厂
 */
public class ThreadPoolDemo implements Runnable {
    private static ThreadPoolExecutor executorService =
            new ThreadPoolExecutor(16, 16,
                    3, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(100));

    @Override
    public void run() {
        System.out.println("1");
        Future<?> submit = executorService.submit(new ThreadPoolDemo());
        try {
            Object o = submit.get(10L, TimeUnit.SECONDS);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 16; i++) {
            executorService.execute(new ThreadDemo22());
        }

        Thread.sleep(5000);

        for (int i = 0; i < 16; i++) {
            executorService.execute(new ThreadDemo22());
        }

    }


}
class ThreadDemo22 implements Runnable{

    @Override
    public void run() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        System.out.println(Thread.currentThread().getName());
    }
}

